Если без триггеров делать, то можно открыть через War3ModelEditor стандартную модель огня и посмотреть, как там устроен источник звука. Потом открыть свою модель и создать в ней такой же источник звука, не забыв настроить время срабатывания.
Хорошо, без триггеров пусть... Я открывал стандартную модель огня, там вообще нету прицепки звука, потому что в доступных звуках в прицепки нету звука огня. Стандартные звуки все на тему заклинаний, но нету звуков окружения, и нету даже похожего звука бушующего огня! Видимо те стандартные модели огня имеют внешнюю прицепку звука, но не в себе. Я бы не спрашивал если бы проблема не была такой слишком сложной. Не люблю зря беспокоить людей.
Тип передвижения на Нет ставишь?
Хотя, если здание, значит прямоугольная карта путей по игровой сетке, а не любое местоположение. Тип передвижения в этом случае не важен.
Я думаю кроме нас тут уже больше никто не напишет поэтому я закрою вопрос, спасибо за внимание и ответы.
Omg_bounty_lord, при создании юнита через CreateNUnitsAtLoc (Создать юнита(ов) с заданным углом поворота) появляется вроде 1-2 утечки, у тебя скорее комп зависнет на 1-5 фпс от кол-ва юнитов, чем варик крашнется из-за этого
Можешь в лс кинуть сам триггер со спавном и какие триггеры реагируют на него?
Если под декорациями ты имеешь ввиду дудадлы, то поставь на одном и том же месте разрушенное и целое здание, а триггерно уже проигрывай анимации hide/show, если же ты про деструкты, то для них есть функции создания/удаления и т.д. Что с почвой не должно получиться? В триггерах есть функции с заменой почвы
Объясню, почему я удалил код: после проведённого за кодом времени, я понял, что сильно погорячился, задав такой глупый вопрос. Стоило отдохнуть, проветрить голову, и решение нашлось. Тем, кто столкнулся с хоть самую малость, но похожей проблемой, дам совет: всегда проверяйте соответствия заклинаний, написанных в коде jass (CTRL + D, если кто не знает, как узнать id заклинания) и ,конечно, сам синтаксис. Также посоветую не утраивать "свалку" в коде, как это сделал я. В общем, если кому интересно, как я решил проблему, пишите - расскажу или даже помогу если у вас она схожая.(Всё дело во внимательности)...
Сброшу код триггера таким, каким я его хотел видеть изначально:
function MU_Check_lvl_four takes nothing returns boolean
if ( not ( GetUnitAbilityLevelSwapped('A011', udg_Akame_Killer) == 4 ) ) then
return false
endif
return true
endfunction
function MU_Check_lvl_three takes nothing returns boolean
if ( not ( GetUnitAbilityLevelSwapped('A011', udg_Akame_Killer) == 3 ) ) then
return false
endif
return true
endfunction
function MU_Check_lvl_two takes nothing returns boolean
if ( not ( GetUnitAbilityLevelSwapped('A011', udg_Akame_Killer) == 2 ) ) then
return false
endif
return true
endfunction
function MU_Check_lvl_one takes nothing returns boolean
if ( not ( GetUnitAbilityLevelSwapped('A011', udg_Akame_Killer) == 1 ) ) then
return false
endif
return true
endfunction
function MU_Second_Conditions takes nothing returns boolean
if ( not ( UnitHasBuffBJ(GetEventDamageSource(), 'B008') == true ) ) then
return false
endif
if ( not ( GetEventDamageSource() == udg_Akame_Killer ) ) then
return false
endif
return true
endfunction
function MU_Start_Conditions takes nothing returns boolean
if ( not ( UnitHasBuffBJ(GetAttacker(), 'B008') == true ) ) then
return false
endif
if ( not ( GetAttacker() == udg_Akame_Killer ) ) then
return false
endif
return true
endfunction
function Trig_MU_Conditions takes nothing returns boolean
if ( not MU_Start_Conditions() ) then
return false
endif
return true
endfunction
function MU_Venum_Check takes nothing returns boolean
if ( not ( udg_MU_Venum_counter == 2 ) ) then
return false
endif
return true
endfunction
function MU_del takes nothing returns nothing
if ( MU_Check_lvl_one() ) then
call SetPlayerAbilityAvailableBJ( true, 'A00X', GetOwningPlayer(GetEventDamageSource()) )
call UnitRemoveAbilityBJ( 'A00X', GetEventDamageSource() )
else
if ( MU_Check_lvl_two() ) then
call SetPlayerAbilityAvailableBJ( true, 'A00U', GetOwningPlayer(GetEventDamageSource()) )
call UnitRemoveAbilityBJ( 'A00U', GetEventDamageSource() )
else
if ( MU_Check_lvl_three() ) then
call SetPlayerAbilityAvailableBJ( true, 'A00Y', GetOwningPlayer(GetEventDamageSource()) )
call UnitRemoveAbilityBJ( 'A00Y', GetEventDamageSource() )
else
if ( MU_Check_lvl_four() ) then
call SetPlayerAbilityAvailableBJ( true, 'A013', GetOwningPlayer(GetEventDamageSource()) )
call UnitRemoveAbilityBJ( 'A013', GetEventDamageSource() )
else
call DoNothing( )
endif
endif
endif
endif
endfunction
function Trig_MU_Actions takes nothing returns nothing
call DestroyTrigger(udg_MU_trig)
set udg_MU_Venum_counter = GetRandomInt(1, 5)
set udg_MU_TG = GetAttackedUnitBJ()
if ( MU_Venum_Check() ) then
if ( MU_Check_lvl_one() ) then
call UnitAddAbilityBJ( 'A00X', udg_Akame_Killer )
call SetPlayerAbilityAvailableBJ( false, 'A00X', GetOwningPlayer(udg_Akame_Killer) )
else
if ( MU_Check_lvl_two() ) then
call UnitAddAbilityBJ( 'A00U', udg_Akame_Killer )
call SetPlayerAbilityAvailableBJ( false, 'A00U', GetOwningPlayer(udg_Akame_Killer) )
else
if ( MU_Check_lvl_three() ) then
call UnitAddAbilityBJ( 'A00Y', udg_Akame_Killer )
call SetPlayerAbilityAvailableBJ( false, 'A00Y', GetOwningPlayer(udg_Akame_Killer) )
else
if ( MU_Check_lvl_four() ) then
call UnitAddAbilityBJ( 'A013', udg_Akame_Killer )
call SetPlayerAbilityAvailableBJ( false, 'A013', GetOwningPlayer(udg_Akame_Killer) )
else
call DoNothing( )
endif
endif
endif
endif
set udg_MU_trig = CreateTrigger()
call TriggerRegisterUnitEvent( udg_MU_trig, udg_MU_TG, EVENT_UNIT_DAMAGED )
call TriggerAddCondition( udg_MU_trig, Condition( function MU_Second_Conditions ) )
call TriggerAddAction( udg_MU_trig, function MU_del )
else
call DoNothing( )
endif
endfunction
//===========================================================================
function InitTrig_MU takes nothing returns nothing
set gg_trg_MU = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_MU, EVENT_PLAYER_UNIT_ATTACKED )
call TriggerAddCondition( gg_trg_MU, Condition( function Trig_MU_Conditions ) )
call TriggerAddAction( gg_trg_MU, function Trig_MU_Actions )
endfunction
Суть триггера:
Имеется способность с четырьмя уровнями. На каждом уровне урон способности разный, а шанс срабатывания всегда 25%. При атаке герой, имеющий такую способность имеет шанс (25%) на отравление противника.
Переменная udg_Akame_killer равносильна GetEventDamageSource()
P.S. Возможно кому-то даже пригодится этот код... Сделан полнейшим неумехой в плане jass, так что не судите строго!
Я не понимаю как вы собираете решать (потому что не даете ответ развернутый). Так вот решение:
решение один. добавить в условие проверку на тип
тут нужно вместо hfoo поставить свой тип
function DuelChecking takes nothing returns nothing
local integer alliance_number=0
local integer akatsuki_number=0
local integer alliance_current=0
local integer akatsuki_current=0
local integer i=0
local unit hero_duel_1=null
local unit hero_duel_2=null
//идет первый цикл
//здесь введены специально счетчики для игроков от каждой команды
// alliance_number - кол-во играющих за добро и akatsuki_number - кол-во играющих за зло
//перебирает всех 10 игроков, если игрок играет, то прибавляет в счетчик
//эти счетчики - переменные целые. они высчитывают шанс.
loop
if i!=4 and i!=5 then
if GetPlayerSlotState(Player(i))==PLAYER_SLOT_STATE_PLAYING then
if i<4 then //<=здесь можно выставить условие ( GetUnitTypeId(udg_Hero[i]) != 'hfoo' ) выставите тип, и тогда счетчик не засчитаете его
set alliance_number=alliance_number+1
elseif i>5 then //<=или здесь можно выставить условие ( GetUnitTypeId(udg_Hero[i]) != 'hfoo' ) выставите тип, и тогда счетчик не засчитаете его
set akatsuki_number=akatsuki_number+1
endif
endif
endif
set i=i+1
exitwhen i>10
endloop
//идет второй цикл
//теперь снова перебираем тех же игроков.
//но пытаемся выдать шанс на то, что герой этого игрока выйдет на дуэль
set i=0
loop
if i!=4 and i!=5 then
if GetPlayerSlotState(Player(i))==PLAYER_SLOT_STATE_PLAYING then //если игрок играет
if i<4 and hero_duel_1==null then //если первый дуэлянт еще не выбран (дуэлянт выбирается от 1 до 4 игрока)
set alliance_current=alliance_current+1 //< странно эти переменная ничего не делает дальше.
//должна alliance_current по идее вычитать из общее количества. из этого шанс будет становится больше.
//например 3 игрока. 1/3=0.3 или 30 процентов. 2 игрока - 1/2=0.5 или 50 процентов
//if ( GetUnitTypeId(udg_Hero[i]) != 'hfoo' ) then <= здесь нужно поставить условие, тогда нагато никогда не выйдет на арену
if alliance_current<alliance_number then
if GetRandomInt(1,alliance_number)==1 then //выбирается рандомно.
set hero_duel_1=udg_Hero[i]
endif
elseif alliance_current==alliance_number then //если дуэлянт не выбран (если до этого шанс не выпад, то выбираем последнего игрока)
set hero_duel_1=udg_Hero[i]
endif
//endif
elseif i>5 and hero_duel_2==null then
set akatsuki_current=akatsuki_current+1 //< странно эти переменная ничего не делает дальше.
//должна akatsuki_current по идее вычитать из общее количества. из этого шанс будет становится больше.
//например 3 игрока. 1/3=0.3 или 30 процентов. 2 игрока - 1/2=0.5 или 50 процентов
//if ( GetUnitTypeId(udg_Hero[i]) != 'hfoo' ) then <= здесь нужно поставить условие, тогда нагато никогда не выйдет на арену
if akatsuki_current<akatsuki_number then
if GetRandomInt(1,akatsuki_number)==1 then //выбирается рандомно шанс
set hero_duel_2=udg_Hero[i]
endif
elseif akatsuki_current==akatsuki_number then
set hero_duel_2=udg_Hero[i]
endif
//endif
endif
endif
endif
set i=i+1
exitwhen i>10 or hero_duel_2!=null
endloop
if hero_duel_1!=null and hero_duel_2!=null then
call DuelStart(GetOwningPlayer(hero_duel_1),GetOwningPlayer(hero_duel_2))
else
call DisplayTimedTextToPlayer(GetLocalPlayer(),0.,0.,5.,"|cFFFFCC00Дуэль не состоялась!|r")
endif
set hero_duel_1=null
set hero_duel_2=null
endfunction
типы
какой из них имба? основное тело героя O014? кого из них отключать?
или может исключить имбу, а клонов в бой на арену? тогда придеться переделать систему.
функцию DuelPrestart надо перезаписать.
только вызывают целые вопросы. клоны - герои. если они мертвы, перед ареной их оживить, после арены убить?
есть карта я код с всеми способности нагато отсортировал для удобства
по поводу переключения
триггер выбора
function Nagato___PainClickGetJutsuCheck takes string str,integer whatValue returns integer
local integer l__Nagato_value=0
if str=="влево"then
if whatValue==5 then
if Nagato_PainExist[5]then
set l__Nagato_value=5
elseif Nagato_PainExist[4]then
set l__Nagato_value=4
elseif Nagato_PainExist[3]then
set l__Nagato_value=3
elseif Nagato_PainExist[2]then
set l__Nagato_value=2
elseif Nagato_PainExist[1]then
set l__Nagato_value=1
elseif Nagato_PainExist[6]then
set l__Nagato_value=6
endif
elseif whatValue==4 then
if Nagato_PainExist[4]then
set l__Nagato_value=4
elseif Nagato_PainExist[3]then
set l__Nagato_value=3
elseif Nagato_PainExist[2]then
set l__Nagato_value=2
elseif Nagato_PainExist[1]then
set l__Nagato_value=1
elseif Nagato_PainExist[6]then
set l__Nagato_value=6
elseif Nagato_PainExist[5]then
set l__Nagato_value=5
endif
elseif whatValue==3 then
if Nagato_PainExist[3]then
set l__Nagato_value=3
elseif Nagato_PainExist[2]then
set l__Nagato_value=2
elseif Nagato_PainExist[1]then
set l__Nagato_value=1
elseif Nagato_PainExist[6]then
set l__Nagato_value=6
elseif Nagato_PainExist[5]then
set l__Nagato_value=5
elseif Nagato_PainExist[4]then
set l__Nagato_value=4
endif
elseif whatValue==2 then
if Nagato_PainExist[2]then
set l__Nagato_value=2
elseif Nagato_PainExist[1]then
set l__Nagato_value=1
elseif Nagato_PainExist[6]then
set l__Nagato_value=6
elseif Nagato_PainExist[5]then
set l__Nagato_value=5
elseif Nagato_PainExist[4]then
set l__Nagato_value=4
elseif Nagato_PainExist[3]then
set l__Nagato_value=3
endif
elseif whatValue==1 then
if Nagato_PainExist[1]then
set l__Nagato_value=1
elseif Nagato_PainExist[6]then
set l__Nagato_value=6
elseif Nagato_PainExist[5]then
set l__Nagato_value=5
elseif Nagato_PainExist[4]then
set l__Nagato_value=4
elseif Nagato_PainExist[3]then
set l__Nagato_value=3
elseif Nagato_PainExist[2]then
set l__Nagato_value=2
endif
elseif whatValue==6 then
if Nagato_PainExist[6]then
set l__Nagato_value=6
elseif Nagato_PainExist[5]then
set l__Nagato_value=5
elseif Nagato_PainExist[4]then
set l__Nagato_value=4
elseif Nagato_PainExist[3]then
set l__Nagato_value=3
elseif Nagato_PainExist[2]then
set l__Nagato_value=2
elseif Nagato_PainExist[1]then
set l__Nagato_value=1
endif
endif
elseif str=="вправо"then
if whatValue==2 then
if Nagato_PainExist[2]then
set l__Nagato_value=2
elseif Nagato_PainExist[3]then
set l__Nagato_value=3
elseif Nagato_PainExist[4]then
set l__Nagato_value=4
elseif Nagato_PainExist[5]then
set l__Nagato_value=5
elseif Nagato_PainExist[6]then
set l__Nagato_value=6
elseif Nagato_PainExist[1]then
set l__Nagato_value=1
endif
elseif whatValue==3 then
if Nagato_PainExist[3]then
set l__Nagato_value=3
elseif Nagato_PainExist[4]then
set l__Nagato_value=4
elseif Nagato_PainExist[5]then
set l__Nagato_value=5
elseif Nagato_PainExist[6]then
set l__Nagato_value=6
elseif Nagato_PainExist[1]then
set l__Nagato_value=1
elseif Nagato_PainExist[2]then
set l__Nagato_value=2
endif
elseif whatValue==4 then
if Nagato_PainExist[4]then
set l__Nagato_value=4
elseif Nagato_PainExist[5]then
set l__Nagato_value=5
elseif Nagato_PainExist[6]then
set l__Nagato_value=6
elseif Nagato_PainExist[1]then
set l__Nagato_value=1
elseif Nagato_PainExist[2]then
set l__Nagato_value=2
elseif Nagato_PainExist[3]then
set l__Nagato_value=3
endif
elseif whatValue==5 then
if Nagato_PainExist[5]then
set l__Nagato_value=5
elseif Nagato_PainExist[6]then
set l__Nagato_value=6
elseif Nagato_PainExist[1]then
set l__Nagato_value=1
elseif Nagato_PainExist[2]then
set l__Nagato_value=2
elseif Nagato_PainExist[3]then
set l__Nagato_value=3
elseif Nagato_PainExist[4]then
set l__Nagato_value=4
endif
elseif whatValue==6 then
if Nagato_PainExist[6]then
set l__Nagato_value=6
elseif Nagato_PainExist[1]then
set l__Nagato_value=1
elseif Nagato_PainExist[2]then
set l__Nagato_value=2
elseif Nagato_PainExist[3]then
set l__Nagato_value=3
elseif Nagato_PainExist[4]then
set l__Nagato_value=4
elseif Nagato_PainExist[5]then
set l__Nagato_value=5
endif
endif
endif
return l__Nagato_value
endfunction
function cj_anonym__523 takes nothing returns nothing
set Nagato_painClickSound=false
call DestroyTimer(GetExpiredTimer())
endfunction
function Nagato___PainClickGetJutsu takes integer id,unit u,string str returns nothing
local boolean camLog=false
local integer i=1
loop
if Nagato_JutsuActive[i]!=0 then
call SetPlayerAbilityAvailable(Nagato_p,Nagato_JutsuActive[i],false)
endif
set i=i+1
exitwhen i>5
endloop
if str=="клик"then
set Nagato_PainSelectedNumberNext=0
if id==Nagato_PAIN_ID_1 then
set Nagato_JutsuActive[1]=0x41303959//A09Y
set Nagato_JutsuActive[2]=0x4130395A//A09Z
set Nagato_JutsuActive[3]=0x4130574C//A0WL
set Nagato_JutsuActive[4]=0x41304833//A0H3
set Nagato_JutsuActive[5]=0x41304530//A0E0
call Sound3D(u,"Nagato Pain 1 Chikushodo.mp3")
elseif id==Nagato_PAIN_ID_2 then
set Nagato_JutsuActive[1]=0x41304842//A0HB
set Nagato_JutsuActive[2]=0
set Nagato_JutsuActive[3]=0
set Nagato_JutsuActive[4]=0
set Nagato_JutsuActive[5]=0
call Sound3D(u,"Nagato Pain 2 Gakido.mp3")
elseif id==Nagato_PAIN_ID_3 then
set Nagato_JutsuActive[1]=0x41305730//A0W0
set Nagato_JutsuActive[2]=0
set Nagato_JutsuActive[3]=0
set Nagato_JutsuActive[4]=0
set Nagato_JutsuActive[5]=0
call Sound3D(u,"Nagato Pain 3 Ningendo.mp3")
elseif id==Nagato_PAIN_ID_4 then
set Nagato_JutsuActive[1]=0x41304157//A0AW
set Nagato_JutsuActive[2]=0x41304543//A0EC
set Nagato_JutsuActive[3]=0
set Nagato_JutsuActive[4]=0
set Nagato_JutsuActive[5]=0
call Sound3D(u,"Nagato Pain 4 Shurado.mp3")
elseif id==Nagato_PAIN_ID_5 then
set Nagato_JutsuActive[1]=0x41304741//A0GA
set Nagato_JutsuActive[2]=0x41305658//A0VX
set Nagato_JutsuActive[3]=0
set Nagato_JutsuActive[4]=0
set Nagato_JutsuActive[5]=0
call Sound3D(u,"Nagato Pain 5 Jigokudo.mp3")
elseif id==Nagato_PAIN_ID_6 then
set Nagato_JutsuActive[1]=0x41303551//A05Q
set Nagato_JutsuActive[2]=0x41303534//A054
set Nagato_JutsuActive[3]=0x41303457//A04W
set Nagato_JutsuActive[4]=0
set Nagato_JutsuActive[5]=0
call Sound3D(u,"Nagato Pain 6 Tendo.mp3")
endif
elseif str=="влево"then
set camLog=true
if Nagato_PainSelectedNumberNext==0 then
if Nagato_PainExist[6]then
set Nagato_PainSelectedNumberNext=6
elseif Nagato_PainExist[5]then
set Nagato_PainSelectedNumberNext=5
elseif Nagato_PainExist[4]then
set Nagato_PainSelectedNumberNext=4
elseif Nagato_PainExist[3]then
set Nagato_PainSelectedNumberNext=3
elseif Nagato_PainExist[2]then
set Nagato_PainSelectedNumberNext=2
elseif Nagato_PainExist[1]then
set Nagato_PainSelectedNumberNext=1
endif
endif
if Nagato_PainExist[6]and Nagato_PainSelectedNumberNext==6 then
set u=Nagato___PainUnit[6]
set Nagato_PainSelectedNumberNext=Nagato___PainClickGetJutsuCheck("влево",5)
set Nagato_JutsuActive[1]=0x41303551
set Nagato_JutsuActive[2]=0x41303534
set Nagato_JutsuActive[3]=0x41303457
set Nagato_JutsuActive[4]=0
set Nagato_JutsuActive[5]=0
call Sound3D(u,"Nagato Pain 6 Tendo.mp3")
elseif Nagato_PainExist[5]and Nagato_PainSelectedNumberNext==5 then
set u=Nagato___PainUnit[5]
set Nagato_PainSelectedNumberNext=Nagato___PainClickGetJutsuCheck("влево",4)
set Nagato_JutsuActive[1]=0x41304741
set Nagato_JutsuActive[2]=0x41305658
set Nagato_JutsuActive[3]=0
set Nagato_JutsuActive[4]=0
set Nagato_JutsuActive[5]=0
call Sound3D(u,"Nagato Pain 5 Jigokudo.mp3")
elseif Nagato_PainExist[4]and Nagato_PainSelectedNumberNext==4 then
set u=Nagato___PainUnit[4]
set Nagato_PainSelectedNumberNext=Nagato___PainClickGetJutsuCheck("влево",3)
set Nagato_JutsuActive[1]=0x41304157
set Nagato_JutsuActive[2]=0x41304543
set Nagato_JutsuActive[3]=0
set Nagato_JutsuActive[4]=0
set Nagato_JutsuActive[5]=0
call Sound3D(u,"Nagato Pain 4 Shurado.mp3")
elseif Nagato_PainExist[3]and Nagato_PainSelectedNumberNext==3 then
set u=Nagato___PainUnit[3]
set Nagato_PainSelectedNumberNext=Nagato___PainClickGetJutsuCheck("влево",2)
set Nagato_JutsuActive[1]=0x41305730
set Nagato_JutsuActive[2]=0
set Nagato_JutsuActive[3]=0
set Nagato_JutsuActive[4]=0
set Nagato_JutsuActive[5]=0
call Sound3D(u,"Nagato Pain 3 Ningendo.mp3")
elseif Nagato_PainExist[2]and Nagato_PainSelectedNumberNext==2 then
set u=Nagato___PainUnit[2]
set Nagato_PainSelectedNumberNext=Nagato___PainClickGetJutsuCheck("влево",1)
set Nagato_JutsuActive[1]=0x41304842
set Nagato_JutsuActive[2]=0
set Nagato_JutsuActive[3]=0
set Nagato_JutsuActive[4]=0
set Nagato_JutsuActive[5]=0
call Sound3D(u,"Nagato Pain 2 Gakido.mp3")
elseif Nagato_PainExist[1]and Nagato_PainSelectedNumberNext==1 then
set u=Nagato___PainUnit[1]
set Nagato_PainSelectedNumberNext=Nagato___PainClickGetJutsuCheck("влево",6)
set Nagato_JutsuActive[1]=0x41303959
set Nagato_JutsuActive[2]=0x4130395A
set Nagato_JutsuActive[3]=0x4130574C
set Nagato_JutsuActive[4]=0x41304833
set Nagato_JutsuActive[5]=0x41304530
call Sound3D(u,"Nagato Pain 1 Chikushodo.mp3")
endif
elseif str=="вправо"then
set camLog=true
if Nagato_PainSelectedNumberNext==0 then
if Nagato_PainExist[1]then
set Nagato_PainSelectedNumberNext=1
elseif Nagato_PainExist[2]then
set Nagato_PainSelectedNumberNext=2
elseif Nagato_PainExist[3]then
set Nagato_PainSelectedNumberNext=3
elseif Nagato_PainExist[4]then
set Nagato_PainSelectedNumberNext=4
elseif Nagato_PainExist[5]then
set Nagato_PainSelectedNumberNext=5
elseif Nagato_PainExist[6]then
set Nagato_PainSelectedNumberNext=6
endif
endif
if Nagato_PainExist[1]and Nagato_PainSelectedNumberNext==1 then
set u=Nagato___PainUnit[1]
set Nagato_PainSelectedNumberNext=Nagato___PainClickGetJutsuCheck("вправо",2)
set Nagato_JutsuActive[1]=0x41303959
set Nagato_JutsuActive[2]=0x4130395A
set Nagato_JutsuActive[3]=0x4130574C
set Nagato_JutsuActive[4]=0x41304833
set Nagato_JutsuActive[5]=0x41304530
call Sound3D(u,"Nagato Pain 1 Chikushodo.mp3")
elseif Nagato_PainExist[2]and Nagato_PainSelectedNumberNext==2 then
set u=Nagato___PainUnit[2]
set Nagato_PainSelectedNumberNext=Nagato___PainClickGetJutsuCheck("вправо",3)
set Nagato_JutsuActive[1]=0x41304842
set Nagato_JutsuActive[2]=0
set Nagato_JutsuActive[3]=0
set Nagato_JutsuActive[4]=0
set Nagato_JutsuActive[5]=0
call Sound3D(u,"Nagato Pain 2 Gakido.mp3")
elseif Nagato_PainExist[3]and Nagato_PainSelectedNumberNext==3 then
set u=Nagato___PainUnit[3]
set Nagato_PainSelectedNumberNext=Nagato___PainClickGetJutsuCheck("вправо",4)
set Nagato_JutsuActive[1]=0x41305730
set Nagato_JutsuActive[2]=0
set Nagato_JutsuActive[3]=0
set Nagato_JutsuActive[4]=0
set Nagato_JutsuActive[5]=0
call Sound3D(u,"Nagato Pain 3 Ningendo.mp3")
elseif Nagato_PainExist[4]and Nagato_PainSelectedNumberNext==4 then
set u=Nagato___PainUnit[4]
set Nagato_PainSelectedNumberNext=Nagato___PainClickGetJutsuCheck("вправо",5)
set Nagato_JutsuActive[1]=0x41304157
set Nagato_JutsuActive[2]=0x41304543
set Nagato_JutsuActive[3]=0
set Nagato_JutsuActive[4]=0
set Nagato_JutsuActive[5]=0
call Sound3D(u,"Nagato Pain 4 Shurado.mp3")
elseif Nagato_PainExist[5]and Nagato_PainSelectedNumberNext==5 then
set u=Nagato___PainUnit[5]
set Nagato_PainSelectedNumberNext=Nagato___PainClickGetJutsuCheck("вправо",6)
set Nagato_JutsuActive[1]=0x41304741
set Nagato_JutsuActive[2]=0x41305658
set Nagato_JutsuActive[3]=0
set Nagato_JutsuActive[4]=0
set Nagato_JutsuActive[5]=0
call Sound3D(u,"Nagato Pain 5 Jigokudo.mp3")
elseif Nagato_PainExist[6]and Nagato_PainSelectedNumberNext==6 then
set u=Nagato___PainUnit[6]
set Nagato_PainSelectedNumberNext=Nagato___PainClickGetJutsuCheck("вправо",1)
set Nagato_JutsuActive[1]=0x41303551
set Nagato_JutsuActive[2]=0x41303534
set Nagato_JutsuActive[3]=0x41303457
set Nagato_JutsuActive[4]=0
set Nagato_JutsuActive[5]=0
call Sound3D(u,"Nagato Pain 6 Tendo.mp3")
endif
endif
set i=1
loop
if Nagato_PainExist[i]then
if Nagato___PainUnit[i]==u then
call SetTextTagColor(Nagato___PainText[i],165,253,0,0)
else
call SetTextTagColor(Nagato___PainText[i],255,255,255,0)
endif
endif
set i=i+1
exitwhen i>6
endloop
set i=1
loop
if Nagato_JutsuActive[i]!=0 then
if GetUnitAbilityLevel(Nagato_c,Nagato_JutsuActive[i])>0 then
call SetPlayerAbilityAvailable(Nagato_p,Nagato_JutsuActive[i],true)
else
call UnitAddAbility(Nagato_c,Nagato_JutsuActive[i])
endif
endif
set i=i+1
exitwhen i>5
endloop
set Nagato_painClickSound=true
call TimerStart(CreateTimer(),1.,false,function cj_anonym__523)
if GetLocalPlayer()==Nagato_p then
call ClearSelection()
call SelectUnit(Nagato_c,true)
endif
if camLog then
if GetLocalPlayer()==Nagato_p then
call ResetToGameCamera(0.)
call PanCameraToTimed(GetWidgetX(u),GetWidgetY(u),0.)
endif
endif
set Nagato___PainClicked=null
endfunction
function Nagato___PainClickConditions takes nothing returns boolean
return GetTriggerPlayer()==Nagato_p and IsUnitPain(GetTriggerUnit())and Nagato___PainClickNumber<2
endfunction
function cj_anonym__524 takes nothing returns nothing
set Nagato___PainClickNumber=Nagato___PainClickNumber-1
call DestroyTimer(GetExpiredTimer())
endfunction
function Nagato___PainClickActions takes nothing returns nothing
local unit u=GetTriggerUnit()
local integer i=1
set Nagato___PainClickNumber=Nagato___PainClickNumber+1
if not Nagato___PainFirst then
set Nagato___PainFirst=true
call DisplayTimedTextToPlayer(Nagato_p,0.,0.,20.,"|cFFFF5000Чтобы открыть способности Пейнов, используйте стрелки влево-вправо-вниз на клавиатуре, либо в течение 0,25 секунд выберите нужного Пейна дважды!|r")
endif
if Nagato___PainClickNumber==1 then
set Nagato___PainClicked=u
endif
if Nagato___PainClickNumber==2 and u==Nagato___PainClicked then
call Nagato___PainClickGetJutsu(GetUnitTypeId(u),u,"клик")//+
endif
call TimerStart(CreateTimer(),.25,false,function cj_anonym__524)//+
set u=null
endfunction
кнопки переключения
function Nagato___PainKeyDownConditions takes nothing returns boolean
return GetUnitAbilityLevel(udg_Hero[GetPlayerId(GetTriggerPlayer())],Nagato_RIKUDO_CANCEL)>0
endfunction
function Nagato___PainKeyDownActions takes nothing returns nothing
local integer i=1
if GetLocalPlayer()==Nagato_p then
call ClearSelection()
call SelectUnit(Nagato_c,true)
endif
loop
if Nagato_PainExist[i]then
if GetLocalPlayer()==Nagato_p then
call SelectUnit(Nagato___PainUnit[i],true)
endif
endif
set i=i+1
exitwhen i>6
endloop
endfunction
function Nagato___PainKeyRightConditions takes nothing returns boolean
return GetUnitAbilityLevel(udg_Hero[GetPlayerId(GetTriggerPlayer())],Nagato_RIKUDO_CANCEL)>0
endfunction
function Nagato___PainKeyRightActions takes nothing returns nothing
call Nagato___PainClickGetJutsu(0,null,"вправо")
endfunction
function Nagato___PainKeyLeftConditions takes nothing returns boolean
return GetUnitAbilityLevel(udg_Hero[GetPlayerId(GetTriggerPlayer())],Nagato_RIKUDO_CANCEL)>0
endfunction
function Nagato___PainKeyLeftActions takes nothing returns nothing
call Nagato___PainClickGetJutsu(0,null,"влево")
endfunction
Привет! Поковырялся чуток, прикладываю скрин, видео и карту. Буквально: скачиваешь редактор JNGP это продвинутый редактор позволяющий без вазелина с маслом вкатиться в жасс. Чтобы ссылаться на ранее созданную область вместо "mapInitialPlayableArea" необходимо создать область(кто бы мог подумать xd) , создать триггер гуишный, в нём создать например событие юнит входит в область, выбрать эту область, затем конвертировать в жасс и найти это событие, в нем найти параметр rect у функции(в скобочках между запятыми, в видосе подробнее), рекомендую для этого JNGP , он собственно показывает где какой параметр у функций, плюс в нем можно собсна посмотреть все функции чо они делают чо умеют и тогдалее, для оптимизации.
Чтобы выбрать всех в диапазоне нужно будет использовать другую нативку:
Вместо g мелкой вставляешь какую хочешь группу, если не то вставишь то JNGP тебе подскажет в чём ты ошибся и что надо исправить. вместо filter пишешь свой фильтр, ну там в видосе подробнее.
(Это для области) call GroupEnumUnitsInRange(g,GetRectCenterX(gg_rct________________000),GetRectCenterY(gg_rct________________000),900,Condition(function filter) )
(Это для юнита) call GroupEnumUnitsInRange(g,GetUnitX(gg_unit_hfoo_0000),GetUnitY(gg_unit_hfoo_0000),900,Condition(function filter) )
Полный код, разбираемый в видео:
function filter takes nothing returns boolean
call BJDebugMsg("сработало!"+GetUnitName(GetFilterUnit()))
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\Flare\\FlareCaster.mdl",GetFilterUnit(),"origin"))
return GetOwningPlayer(GetFilterUnit()) == Player(0)
endfunction
function Trig_____________________________________001_Actions takes nothing returns nothing
local group g = CreateGroup()
call GroupEnumUnitsInRect(g,gg_rct________________000,Condition(function filter) )
call GroupEnumUnitsInRange(g,GetRectCenterX(gg_rct________________000),GetRectCenterY(gg_rct________________000),900,Condition(function filter) )
call GroupEnumUnitsInRange(g,GetUnitX(gg_unit_hfoo_0000),GetUnitY(gg_unit_hfoo_0000),900,Condition(function filter) )
call DestroyGroup(g)
set g = null
call BJDebugMsg("сработало!")
endfunction
//===========================================================================
function InitTrig_____________________________________001 takes nothing returns nothing
set gg_trg_____________________________________001 = CreateTrigger( )
call TriggerAddAction( gg_trg_____________________________________001, function Trig_____________________________________001_Actions )
endfunction
Каждый вопрос заслуживает отдельного обсуждения, а на все стало лень ответ печатать, когда начал.
Печатать реально долго, легче было реализовать примеры в карте:
Кроме последнего пункта, его нужно персонально рассматривать, так как игра не подразумевает использование для юнита двух списков. Например, можно наполнить список построек у юнита всеми зданиями, часть из которых блокировать при открытии одного списка и разблокировать при открытии второго, но это подходит, когда один рабочий. Можно сделать второй список из книги заклинаний, куда добавлены способности на основе игрушечных строений, чтобы было видно карту пути и всё такое, но там для них используется один приказ, то есть всегда одинаковое здание будет при нажатии на любую способность, а ещё нет стоимости золота и дерева, что тоже придётся как-то ваять триггерно. Можно перевоплощать юнита при смене списка в другого, но там тоже сложности, не помню точно какие, вроде бы связаны с расой, так как все строят по-разному.
С точкой сбора всё просто. Способность у игрока не заблокировать, потому нужно забрать её у всех зданий, которые есть на карте, либо будут построены.
Группа из максимум 9 юнитов работает немножко коряво, ранее мы с PT153 находили какой-то вариант, чтобы работало быстро, но лень пользоваться поиском. Вроде каждую 0.01 секунду проверялось количество выбранных юнитов, лишние удалялись из выбора.
Чтобы не было очереди, пришёл в голову лишь вариант с апгрейдом здания. Но у меня реализован просто пример для одного конкретного здания, а для нескольких абстрактных зданий нужно делать текстовым триггером, который будет для каждого здания запускать локальный таймер на нужное время и добавлять анимационный текстаг work. По отмене апгрейда, либо истечению таймера анимационный тег удаляется и создаётся воин, к которому привязывается соответствующий звук. Но есть и другие варианты, типа создавать внутри здания другое, которое реально будет производить юнитов, когда заказал апгрейд, там иная реализация. И не упомянул про затрачиваемые ресурсы. Потребуется забирать/возвращать часть ресурсов при отмене апгрейда.
На примере триггеров и фиолетовых строк в редакторе объектов смотри, как сделано улучшение Бугая в Дренорского бугая.
Конечно, мог бы сделать MUI триггер на GUI для отсутствия очереди, но это было бы громоздко и в техническом смысле уродливо. производящие здания заносились бы в массив, для которого будет массив таймеров, которые будут заноситься в виде событий на истечение таймера в другой триггер, а точнее будет несколько массивов таймеров, по максимальному числу тренируемых юнитов в любом производящем здании.
Бтв, про сбор команды - для продвинутых сущностей нередко исправлять за другими оказывается тяжелее, чем делать самому, важно создать максимально комфортные условия для созидания, вот для чего деньги не лишние, а уж дело и самому можно делать.
И, да, тема-то не про то, надо это или не надо, а про то, как лучше это сделать, я про это и в стартовом сообщении написал.
Я на крайний сам вопрос по варианту 3 проверю и/или будет сделан выбор между третьим вариантом, вторым, каким-то ещё и отказом от Cooldown Reduction, но если кто поможет - спасибо.
Aws, тогда мой вариант тебе идеально подходит, осталось решить какой необратимый хеш одновременно достаточно хорош и не слишком сложен в реализации. Я помню кто-то даже md5 на jass выкладывал тут на xgm, но, имхо, это изврат.
Принцип примерно такой:
игрок вводит команду вида "-code qwerty", где code это или универсальное ключевое слово для ввода кодов или уникальное для каждого кода, в зависимости от реализации, а qwerty это ключевое слово для конкретного кода
триггер отлавливает ввод первого ключевого слова "-code" и выделяет из строки второе ключевое слово "qwerty"
ключевое слово "qwerty" прогоняется через необратимую хеш-функцию и превращается в хеш "123456"
хеш "123456" сравнивается с записаным в карте хешем, циклом если команда "-сode" универсальная, или напрямую если у каждого кода есть своя команда
если хеш совпал, то выдаем плюшки, ну а если нет, то шлем нах
при попытке вскрыть карту кулхацкер обнаружит только "-code" и "123456", но не "qwerty", а значит не сможет правильно ввести команду в официальной версии карты
наличие алгоритма хеширования в карте не спасает кулхацкера т.к. алгоритм необоратимый и не может из "123456" получить "qwerty"
кулхацкер может поробовать подобрать ключевое слово, хеш которого совпадет с "123456", но если функция хеширования достаточно хороша, то он скорее начнет рвать волосы на жопе и визжа кататься по полу, чем у него это получится
вот карта
неправильно используешь константы, лень объяснять.
Короче, тут его один баг. Ты всех вурдалаков вначале отправляешь разрушать ворота, а если выйти и перекрыть им вход? Полностью не перекрыть им вход, но все же вурдалаки проигнорят ваших солдат (ибо отдана атака ворот). Надо сначала сделать так, им дойти до ворот (атака в точку), а после проверить нет ли кого рядом с воротами. И попробовать разрушить (отдать атаковать ворота). Надо кампании посмотреть как там сделано.
Еще надо проверять, если кто-то попытается открыть ворота и выйти.
Мне вот интересно ворота живы, когда они открыты? Просто используется проверка жива/мертва декорация. это не проверял. Если интересно, в одной кампании, чтобы опустить проход, декор разрушают kill.
В моей карте нет ничего этого, что описал. Просто проверяют периодиком жива/декорация, берем группы вурдалаков и отдаем нужные приказы
по итогу просмотровщик на сайте смог сделать больше чем спец софт предназначенный для редактирования моделей
надо было Stand и Death поставить в раскадровке перед всеми остальными анимациями
Вообщем сделал так при нажатие производит анимация и после 5 сек ишет радиус за 500 от героя если рыба -дамми есть то роллим шанса на ловля иначе ни как
Но просто не красиво анимация ловля по земле =)
Почему то на таймере всё забагалось и прилетало по несколько ивентов, сделал на периодическом триггере и всё стало нормально.
Код
globals
region region123
trigger trg = CreateTrigger()
real maxX
real minX
real maxY
real minY
real pointX
real pointY
endglobals
function Run takes nothing returns nothing
if pointY < minY then
call TriggerRegisterEnterRegion( gg_trg_enter, region123, null )
call TriggerRegisterLeaveRegion( gg_trg_leave, region123, null )
call DisableTrigger( trg )
endif
if pointX > maxX then
set pointY = pointY-32.00
set pointX = minX
endif
if IsTerrainPathable(pointX, pointY, PATHING_TYPE_FLOATABILITY) == false then
call RegionAddCell( region123, pointX, pointY )
endif
set pointX = pointX+32.00
endfunction
function Trig_trg_Actions takes nothing returns nothing
set region123 = CreateRegion()
set maxX = GetRectMaxX(bj_mapInitialPlayableArea)
set minX = GetRectMinX(bj_mapInitialPlayableArea)
set maxY = GetRectMaxY(bj_mapInitialPlayableArea)
set minY = GetRectMinY(bj_mapInitialPlayableArea)
set pointX = minX
set pointY = maxY
call TriggerRegisterTimerEvent( trg, 0., true )
call TriggerAddCondition( trg, Condition(function Run) )
endfunction
//===========================================================================
function InitTrig_trg takes nothing returns nothing
call Trig_trg_Actions()
endfunction
Вот карта с примером (карту сохранить не сможешь, т.к тебе нужен будет JNGP, это просто чтобы ты посмотрел сам алгоритм)
И учти что чем больше карта, тем больше времени нужно алгоритму что построить регион
В параметрах карты можно же отключить волны на пологих\крутых берегах. После чего можно добавить модель волны (В одном из ресурсов на XGM была модель волны). И получится один слой волн.
Оооо это Огре , я когда только хотел ланд сделать смотрел его ролики и шарил карту. Но скажу что для его уровня более менее с импорт моделями мне далеко когда я начал импортировать почти каждую модель пришёл к выводу что мне это ненужно и нужно начинать с малого иделать на стандарте и только в необходимых случаях когда действительно не смотриться импортировать. На это уходит много времени хотя относительно ландинга нет , но всё же : Поиск , тестинг моделей занимает время , и мне попросту это по факту и не надо)
Поиск по всем ресурсам на сайте (/search/1?index=qa&query=%D0%A2%D1%80%D0%B8%D0%B3%D0%B3%D0%B5%D1%80%20%D0%BD%D0%B0%20%D0%BA%D0%B0%D0%BC%D0%B5%D1%80%D1%83%20-zoom)
» WarCraft 3 / Как удалить последнюю созданную точку?
» WarCraft 3 / Спавн юнита
» WarCraft 3 / Телепортация к дамми-юниту.
» WarCraft 3 / Араккоа Reforged
» WarCraft 3 / 2 вопроса по Jass-у
» WarCraft 3 / Как Изменить имя игрока?
» WarCraft 3 / Ломаний ИИ
» WarCraft 3 / просто моя первая карта
» WarCraft 3 / Анимации в Retera
» Администрация XGM / Цитирование комментария в ветке.
» WarCraft 3 / нету воды
» WarCraft 3 / Триггер на камеру -zoom
» Chronicles of the Ring REBIRTH / Chronicles of the Ring
» WarCraft 3 / Большой Фанат Дота
» WarCraft 3 / Нападения Короля Лича